package com.flame.shapeville.controller;

import com.flame.shapeville.enums.SceneStyle;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import lombok.Setter;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * Central controller for managing scene transitions.
 * <p>
 * Handles switching between different scenes (e.g., login, main, task, course)
 * and ensures proper initialization of each scene's controller.
 *
 * @author Flame Dev Team
 * @version 1.0
 * @since 2025-05-01
 */
public class SceneController {
    /**
     * Property representing the current scene style.
     */
    private static final ObjectProperty<SceneStyle> sceneStyle = new SimpleObjectProperty<>();

    /**
     * Reference to the primary stage of the application.
     */
    @Setter
    private static Stage primaryStage;
    /**
     * Path to the FXML files for different scenes.
     */
    private static final String FXML_PATH = "/static/fxml/";

    /**
     * Static block to initialize the scene listener.
     */
    static {
        // init scene listener
        sceneStyle.addListener((observable, oldValue, newValue) -> {
            if (newValue != null) {
                switchScene(newValue);
            }
        });
    }
    /**
     * Gets the current scene style property.
     *
     * @return the scene style property
     */
    public static ObjectProperty<SceneStyle> sceneStyleProperty() {
        return sceneStyle;
    }

    /**
     * Sets the current scene style.
     *
     * @param style the new scene style
     */
    public static void setSceneStyle(SceneStyle style) {
        sceneStyle.set(style);
    }

    /**
     * Gets the current scene style.
     *
     * @return the current scene style
     */
    public static SceneStyle getSceneStyle() {
        return sceneStyle.get();
    }

    /**
     * Switches the scene to the specified style.
     *
     * @param style the target scene style
     */
    private static void switchScene(SceneStyle style) {
        if (primaryStage == null) {
            throw new IllegalStateException("Primary stage is not set.");
        }

        FXMLLoader loader = new FXMLLoader(SceneController.class.getResource(FXML_PATH + style.name().toLowerCase() + ".fxml"));
        try {
            Node root = loader.load();
            Scene scene = new Scene((Parent) root);
            ((JfController) loader.getController()).init();
            primaryStage.setScene(scene);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
